<!-- ”menu“，”sysdict“，”oss“和”job“未使用本组件 -->
<template>
  <el-dialog :class="editTableConfig ? 'multiAddOrUpdateDialog' : 'addOrUpdateDialog'"
             v-if="visible"
             :width="`${width}%`"
             :visible.sync="visible"
             :top="top"
             :title="!dataForm[idAttr] ? '新增' : '修改'"
             :close-on-click-modal="false"
             :close-on-press-escape="false"
  >
    <!--  启动分步  -->
    <template v-if="stepsConfig">
      <el-steps :active="activeStep" finish-status="success" align-center>
        <el-step v-for="index in stepNumber" :key="index"
                 :title="R.path(['steps', index - 1, 'title'], stepsConfig)"
                 :description="R.path(['steps', index - 1, 'description'], stepsConfig)"
        ></el-step>
      </el-steps>
      <!--  根据”stepsConfig“和”activeStep“确定当前步骤需要显示的属性名称  -->
      <normal-form
        ref="dataForm"
        :dataForm="dataForm"
        :config="config"
        :showAttrs="showAttrs"
        :dataRule="dataRule"
        :showLabel="true"
        :showAll="true"
        :key="this.dataForm[idAttr]"
        :colFlagFunc="colFlagFunc"
        :submitFunc="R.equals(activeStep + 1, stepNumber) ? finishStep : nextStep"
      ></normal-form>
      <!--  按钮组  -->
      <div class="stepButtonContainer">
        <el-button class="lastStepBtn" v-if="R.lt(0, activeStep)" @click="lastStep">上一步</el-button>
        <el-button class="nextStepBtn" v-if="R.gt(stepNumber - 1, activeStep)" @click="nextStep">下一步</el-button>
        <el-button class="finishStepBtn" v-if="R.equals(stepNumber - 1, activeStep)" :loading="btnLoading"
                   @click="finishStep">
          完成
        </el-button>
      </div>
    </template>

    <template v-else-if="stepsConfigRow">
      <el-steps :active="activeStep" finish-status="success" align-center>
        <el-step v-for="index in stepNumber" :key="index"
                 :title="R.path(['steps', index - 1, 'title'], stepsConfigRow)"
                 :description="R.path(['steps', index - 1, 'description'], stepsConfigRow)"
        ></el-step>
      </el-steps>
      <!--  根据”stepsConfig“和”activeStep“确定当前步骤需要显示的属性名称  -->
      <normal-form
        ref="dataForm"
        :dataForm="dataForm"
        :config="config"
        :showAttrs="showAttrs"
        :dataRule="dataRule"
        :showLabel="true"
        :showAll="true"
        :key="this.dataForm[idAttr]"
        :colFlagFunc="colFlagFunc"
        :submitFunc="R.equals(activeStep + 1, stepNumber) ? finishStep : nextStep"
      ></normal-form>
      <!--  按钮组  -->
      <div class="stepButtonContainer">
        <el-button class="lastStepBtn" v-if="R.lt(0, activeStep)" @click="lastStep">上一步</el-button>
        <el-button class="nextStepBtn" v-if="R.gt(stepNumber - 1, activeStep)" @click="nextStep">下一步</el-button>
        <el-button class="finishStepBtn" v-if="R.equals(stepNumber - 1, activeStep)" :loading="btnLoading"
                   @click="finishStep">
          完成
        </el-button>
      </div>
    </template>

    <!--  未启动分步  -->
    <template v-else>
      <!--  直接显示所有  -->
      <normal-form
        ref="dataForm"
        :dataForm="dataForm"
        :config="config"
        :dataRule="dataRule"
        :showLabel="true"
        :showAll="true"
        :pCheckIsShow='pCheckIsShow'
        :pCheckColRightIsShow='pCheckColRightIsShow'
        :colFlagFunc="colFlagFunc"
        :key="this.dataForm[idAttr]"
      ></normal-form>
      <!--  按钮组  -->
      <span slot="footer" class="dialog-footer">
        <slot name="footer"></slot>
        <el-button v-if='isMulti' >暂存</el-button>
        <el-button @click="visible = false">取消</el-button>
        <el-button  v-preventReClick="2000" type="primary" @click="dataFormSubmit()">确定</el-button>
      </span>
    </template>
    <template v-if='editTableConfig'>
      <edit-table-view ref='editTableView' :config='editTableConfig'></edit-table-view>
    </template>
  </el-dialog>
</template>

<script>
import normalForm from '@/components/normalForm/form'
import editTableView from '@/components/editTableView'
import {mRequest} from '@/utils/request'
import {getFormatDateTime} from '@/utils'
import {specialTypeCheck} from '@/utils'

export default {
  name: 'index',
  components: {
    normalForm,
    editTableView
  },
  props: {
    width: {
      type: Number,
      default: 70
    },
    printWhenSubmit: {
      type: Boolean,
      default: false
    },
    printFunc: {
      type: Function,
      default: null
    },
    top:{
      type: String,
      default: '15vh'
    },
    colFlagFunc:{
      type: Boolean,
      default: true
    }
  },
  computed: {
    /**
     * 根据”stepsConfig“和”activeStep“确定当前步骤需要显示的属性名
     * @returns {Array|*}
     */
    showAttrs() {
      if (this.R.isNil(this.stepsConfig)) {
        return []
      }
      let attrs = this.R.path(['steps', this.activeStep, 'Attrs'], this.stepsConfig)

      if (this.R.isNil(attrs)) {
        const getOtherAttrs = this.R.compose(this.R.difference(Object.keys(this.config)), this.R.unnest, this.R.map(this.R.propOr([], 'Attrs')))

        attrs = getOtherAttrs(this.R.prop('steps', this.stepsConfig))
      }
      return attrs
    },
    /**
     * 分步的数量
     * @returns {*}
     */
    stepNumber() {
      return this.R.length(this.R.propOr([], 'steps', this.stepsConfig))
    },
    isMulti() {
      return !this.R.isNil(this.editTableConfig)
    }
  },
  watch: {
    dataForm: {
      deep: true,
      handler() {
        const dataFormRef = this.$refs.dataForm

        if (this.R.isNil(dataFormRef)) {
          return
        }
        dataFormRef.$refs.components.forEach(item => {
          const componentRef = item.$refs.component

          if (!this.R.isNil(componentRef)) {
            componentRef.$forceUpdate()
          }
        })
      }
    }
  },
  data() {
    return {
      btnLoading: false,
      activeStep: 0,
      dataForm: {},
      config: {},
      editTableConfig: null,
      stepsConfig: null,
      stepsConfigRow: null,
      dataRule: {},
      labelPosition: 'right',
      labelWidth: '130px',
      visible: false,
      initApi: '',
      saveApi: '',
      updateApi: '',
      multiSaveApi: '',
      idAttr: 'id',
      submitCallback: null,
      dateAttrList: ['createTime', 'dayTime', 'putInTime', 'outTime', 'orderTime', 'deliveryTime', 'proofingTime', 'returnTime', 'payTime', 'vouchDate', 'payDate', 'sampleDate','onlineTime', 'contractTime', 'deliveryTime']
    }
  },
  methods: {
    /**
     * 点击”上一步“按钮时触发
     */
    lastStep() {
      if (this.activeStep > 0) {
        this.activeStep = this.activeStep - 1
      }
    },
    /**
     * 点击”下一步“按钮时触发
     */
    nextStep() {
      const dataFormEL = this.getDataForm()

      if (this.R.isNil(dataFormEL)) {
        return
      }
      // 验证填写的内容
      dataFormEL.validate(valid => {
        if (valid) {
          // 执行回调函数
          this.R.pathOr(this.R.F, ['steps', this.activeStep, 'nextFunc'], this.stepsConfig)()
          // 显示下一步骤的属性
          this.$nextTick(() => {
            if (this.activeStep < this.stepNumber) {
              this.activeStep = this.activeStep + 1
              this.$nextTick(() => {
                // v-show的切换会触发验证，首次显示时需要清除验证信息
                dataFormEL.clearValidate()
              })
            }
          })
        }
      })
    },
    /**
     * 点击”完成“按钮时触发
     */
    finishStep() {
      this.dataFormSubmit()
    },
    /**
     * 获取数据表单的 VUE-REF 对象
     * @returns {*|Vue|Element|null|Vue | Element | Vue[] | Element[]}
     */
    getDataForm() {
      if (this.R.isNil(this.$refs['dataForm'])) {
        return null
      }
      if (this.$refs['dataForm'] instanceof Array) {
        return this.$refs['dataForm'][0]
      }
      return this.$refs['dataForm']
    },
    /**
     * 初始化数据表单对象
     */
    initDataForm() {
      if (Object.keys(this.config).length > 0) {
        Object.keys(this.config).forEach((key) => {
          if (!this.R.equals(this.idAttr, key)) {
              let defaultValue = this.R.pathOr('', [key, 'default'], this.config)

            if (defaultValue instanceof Function) {
              defaultValue = defaultValue()
            }
            this.$set(this.dataForm, key, defaultValue)
          }
        })
      }
    },
    /**
     * 初始化对话框
     * @param dataForm 数据表单对象
     * @param config 数据配置对象
     * @param stepsConfig 分布配置对象
     * @param editTableConfig
     * @param multiSaveApi
     * @param dataRule 数据校验规则
     * @param initApi ”初始化“API名称
     * @param saveApi ”保存“API名称
     * @param updateApi ”更新“API名称
     * @param objectName API中的对象名称
     * @param submitCallback submit后的回调函数
     * @param submitAtFinish 最后是否触发向上提交
     * @param idAttr id属性名称
     */
    initDialog({
                 dataForm,
                 config,
                 stepsConfig,
                 editTableConfig,
                 multiSaveApi,
                 dataRule,
                 initApi,
                 saveApi,
                 updateApi,
                 objectName,
                 submitCallback,
                 submitAtFinish = true,
                 idAttr = 'id'
               }) {
      // 各种赋值和初始化
      this.submitAtFinish = submitAtFinish
      this.activeStep = 0
      this.idAttr = idAttr
      this.initApi = initApi
      this.saveApi = saveApi
      this.updateApi = updateApi
      this.submitCallback = submitCallback
      this.objectName = objectName
      this.dataForm = dataForm
      this.stepsConfig = stepsConfig
      this.editTableConfig = editTableConfig
      this.multiSaveApi = multiSaveApi
      this.config = config
      this.dataRule = dataRule
      this.initDataForm()
      if (this.visible) {
        return
      }
      // 开始显示对话框
      this.visible = true

      if (this.isMulti) {
        this.config = {}
        const multiModeKeys = Object.keys(config).filter(key => this.R.propEq('showInMultiMode', true, config[key]))

        multiModeKeys.forEach(key => {
          this.config[key] = config[key]
        })
      }

      this.$nextTick(() => {
        // 判断当前是”新建“还是”更新“
        this.isCreate = !this.dataForm[this.idAttr]
        // 获取”表单“对象
        const dataFormEL = this.getDataForm()

        if (this.R.isNil(dataFormEL)) {
          return
        }
        // 重置表单
        dataFormEL.resetFields()
        // 如果是”更新“
        if (!this.isCreate) {
          // 请求已有数据
          mRequest(this.initApi, {id: this.dataForm[idAttr]}, ({data}) => {
            if (data && data.code === 0) {
              // 对”dataForm“进行初始化赋值
              Object.keys(this.dataForm).forEach((key) => {
                let value = this.R.pathOr(this.dataForm[key], [this.objectName, key], data)
                // 对”时间日期“类对象进行特殊处理
                if (this.R.includes(key, this.dateAttrList)) {
                  value = new Date(value)
                }
                this.dataForm[key] = value
              })
            }
            // 对”dataForm“进行初始化赋值后，执行”数据加载完毕“钩子函数
            this.$nextTick(() => {
              dataFormEL.execDataLoaded()
            })
          })
        } else {
          // 如果是”新建“，直接执行”数据加载完毕“钩子函数
          dataFormEL.execDataLoaded()
        }
      })
    },
    pCheckIsShow(key) {
      if (!this.isMulti) {
        return true
      }
      const tmpAttrConf = this.config[key]

      if (this.R.isNil(tmpAttrConf)) {
        return false
      }
      return tmpAttrConf['showInMultiMode']
    },

    pCheckColRightIsShow(key) {
      if (!this.isMulti) {
        return true
      }
      const tmpAttrConf = this.config[key]

      if (this.R.isNil(tmpAttrConf)) {
        return false
      }
      return tmpAttrConf['showInColRightMode']
    },
    printHandle(data) {
      if (this.R.isNil(this.printFunc)) {
        return
      }

      this.printFunc(data)
    },
    /**
     * submit 数据
     */
    dataFormSubmit() {
      this.btnLoading = true
      const dataFormEL = this.getDataForm()

      if (this.R.isNil(dataFormEL)) {
        this.btnLoading = false
        return
      }
      dataFormEL.validate(valid => {
          if (!valid) {
            this.btnLoading = false
            return
          }
          // 执行各个Input组件的自定义钩子函数
          dataFormEL.execBeforeSubmitFunc()

          let tmpSaveApi = this.saveApi

          if (tmpSaveApi instanceof Function) {
            tmpSaveApi = tmpSaveApi()
          }

        let tmpUpdateApi = this.updateApi

        if (tmpUpdateApi instanceof Function) {
          tmpUpdateApi = tmpUpdateApi()
        }

        const apiName = this.isMulti ? this.multiSaveApi : this.isCreate ? tmpSaveApi : tmpUpdateApi
        if (this.isMulti) {

          this.$refs.editTableView.save()
        }
        const params = this.getSubmitData()

          if (!this.submitAtFinish) {
            console.warn('数据未上传，直接返回')
            this.btnLoading = false
            this.visible = false
            return this.submitCallback(params)
          }

        setTimeout(() => {
          if (this.isMulti) {
            this.$message.error('列表的条数为: ' + params.tableListData.length)
          }
          mRequest(apiName, params, ({data}) => {
            this.btnLoading = false
            const run = () => {
              this.$message({
                message: '操作成功',
                type: 'success',
                duration: 1500,
                onClose: () => {
                  this.btnLoading = false
                  this.visible = false
                  this.$parent.$emit('refreshDataList')
                  if (!this.R.isNil(this.submitCallback)) {
                    this.submitCallback(this.R.prop(this.objectName, data))
                  }
                }
              })
            }

            if (data && data.code === 0) {
              if (this.printWhenSubmit && !this.R.isNil(this.printFunc)) {
                console.log(JSON.stringify(data.list))
                this.$confirm('是否直接打印该数据?', '提示', {
                  confirmButtonText: '确定',
                  cancelButtonText: '取消',
                  type: 'warning'
                }).then(() => {
                  this.printHandle(data.list)
                }).catch(() => {
                  this.$message({
                    type: 'info',
                    message: '已取消打印'
                  })
                }).finally(() => {
                  run()
                })
              } else {
                run()
              }
            } else {
              this.btnLoading = false
              this.$message.error(data.msg)
            }
          })
        }, 1000)

        }
      )
    },
    /**
     * 根据数据表单对象获取submit对象
     */
    getSubmitData() {
      const params = {}

      Object.keys(this.dataForm).forEach((key) => {
        let value = this.dataForm[key]

        if (this.R.equals(this.idAttr, key)) {
          // eslint-disable-next-line no-undefined
          value = value ? value : undefined
        }
        if (this.R.includes(key, this.dateAttrList)) {
          value = getFormatDateTime(value)
        }
        if (this.isMulti) {
          if (this.R.path([key, 'showInMultiMode'], this.config)) {
            params[key] = value
          }
        } else {
          params[key] = value
        }
      })
      if (this.isMulti) {
        // const selectedTableData = this.$refs.editTableView.selectedTableData
        //
        // if (selectedTableData.length > 0) {
        //   params.tableListData = selectedTableData
        // } else {
        //   params.tableListData = this.$refs.editTableView.tableData
        // }
        params.tableListData = this.$refs.editTableView.tableData
      }
      return specialTypeCheck(params)
    }
  }
}
</script>

<style scoped>

</style>
